Skip to content

feat: Add MFA (Multi-Factor Authentication) API support#79

Draft
subhankarmaiti wants to merge 12 commits intomainfrom
feat/mfa-api
Draft

feat: Add MFA (Multi-Factor Authentication) API support#79
subhankarmaiti wants to merge 12 commits intomainfrom
feat/mfa-api

Conversation

@subhankarmaiti
Copy link
Contributor

Adds full MFA API support to auth0-server-python, enabling developers to integrate multi-factor authentication flows into their applications.

New Features

MfaClient — accessible via server_client.mfa

  • list_authenticators(options) — List enrolled authenticators for a user (OTP, OOB/SMS, OOB/Email).
  • enroll_authenticator(options) — Enroll a new authenticator (OTP, SMS, or Email).
  • delete_authenticator(options) — Remove an enrolled authenticator.
  • challenge_authenticator(options) — Trigger an MFA challenge (e.g., send an SMS code).
  • verify(options) — Verify an MFA challenge using OTP, OOB, or a recovery code.
  • encrypt_mfa_token(...) / decrypt_mfa_token(...) — Securely encrypt/decrypt the mfa_token for safe round-tripping through the client (JWE with TTL expiry).

Automatic mfa_required Detection

  • get_access_token() and get_token_by_refresh_token() now detect mfa_required responses from Auth0 and raise MfaRequiredError with an encrypted mfa_token, enabling seamless step-up authentication flows.

Usage Example

from auth0_server_python import ServerClient

client = ServerClient(domain="...", client_id="...", client_secret="...", secret="...")

# MFA is triggered automatically during token retrieval
try:
    token = await client.get_access_token()
except MfaRequiredError as e:
    # e.mfa_token is encrypted and safe to pass to the frontend
    mfa_token = e.mfa_token

# Challenge + verify flow
challenge = await client.mfa.challenge_authenticator({
    "mfa_token": raw_token,
    "challenge_type": "oob",
    "authenticator_id": "auth|123"
})

result = await client.mfa.verify({
    "mfa_token": raw_token,
    "oob_code": challenge.oob_code,
    "binding_code": user_input
})
# result.access_token is now available

@gyaneshgouraw-okta
Copy link

gyaneshgouraw-okta commented Feb 18, 2026

@subhankarmaiti please also add a corresponding example.md file for the mfa api usage in this SDK as done for other features. You can checkout spa js/next SDK example if that helps defining the structure - https://github.com/auth0/auth0-spa-js/blob/main/EXAMPLES.md#multi-factor-authentication-mfa

f"Unexpected error enrolling authenticator: {str(e)}"
)

async def delete_authenticator(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@subhankarmaiti Delete operation is not required as per the requirement. We can remove this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments